<script setup lang="ts">
import { reactive, ref } from "vue";
import type {
  MenuAddType,
  MenuEditType,
  MenuListResType,
} from "@/types/MenuType.ts";
import {
  FormInstance,
  Message,
  TreeNodeData,
  ValidatedError,
} from "@arco-design/web-vue";
import { menuAdd, menuList, menuUpdate } from "@/services/menuApi.ts";
import type { FormRule } from "@/types/commonType.ts";
import router from "@/router";
import MenuIconSelect from "@/components/system/menu-icon-select/menu-icon-select.vue";

const emit = defineEmits<{
  (e: "list"): void;
}>();

const DefineFormModel: MenuEditType = {
  menuType: 0,
  name: "",
  url: "",
  parentId: "",
  component: "",
  componentName: "",
  redirect: "",
  icon: "",
  sortNo: 0,
  isRoute: 0,
  hidden: 0,
  hideTab: 0,
  alwaysShow: 0,
  internalOrExternal: 0,
  id: "",
  perms: "",
  permsType: 1,
  status: "1",
};

const formModel = ref<MenuEditType>(
  JSON.parse(JSON.stringify(DefineFormModel))
);

const rules: FormRule<
  "name" | "url" | "component" | "componentName" | "perms" | "parentId"
> = {
  name: {
    required: true,
    message: "请输入菜单名称",
  },
  url: {
    required: true,
    message: "请输入访问路径",
  },
  component: {
    required: true,
    message: "请输入前端组件",
  },
  componentName: {
    required: true,
    message: "请输入组件名称",
  },
  perms: {
    required: true,
    message: "请输入按钮标识",
  },
  parentId: {
    required: true,
    message: "请选择上级目录",
  },
};

const formRef = ref<FormInstance>();

const option = reactive({
  title: "",
  visible: false,
  type: 0,
});

const treeData = ref<TreeNodeData[]>([]);

const handleCancel = () => {
  option.visible = false;
};

const handleOk = () => {
  formRef.value?.validate(
    (errors: undefined | Record<string, ValidatedError>) => {
      if (errors === undefined) {
        const obj = JSON.parse(JSON.stringify(formModel.value));
        if (obj.menuType === 0) {
          obj.parentId = "";
        }
        if (option.type === 0) {
          delete obj.id;
          menuAdd(obj).then((res) => {
            if (res.code === 200) {
              Message.success(res.msg);
              handleCancel();
              emit("list");
            }
          });
        } else {
          menuUpdate(obj).then((res) => {
            if (res.code === 200) {
              Message.success(res.msg);
              handleCancel();
              emit("list");
              router.go(0);
            }
          });
        }
      }
    }
  );
};
// 新增打开
const show = () => {
  // formModel.value = {
  //   ...DefineFormModel,
  //   menuType: 0,
  // };
  fz();
  menuList()
    .then((res) => {
      if (res.code === 200) {
        treeData.value = res.data;
      }
    })
    .finally(() => {
      option.type = 0;
      formModel.value = DefineFormModel;
      option.visible = true;
      option.title = "新增菜单";
    });
};
// 编辑打开
const edit = (row: MenuListResType) => {
  menuList()
    .then((res) => {
      if (res.code === 200) {
        treeData.value = res.data;
      }
    })
    .finally(() => {
      for (const key in formModel.value) {
        if (Object.prototype.hasOwnProperty.call(row, key)) {
          formModel.value[key] = row[key]!;
        }
      }
      option.type = 1;
      option.visible = true;
      option.title = "编辑菜单";
    });
};

const fz = () => {
  formModel.value.menuType = 0;
  formModel.value.name = "";
  formModel.value.url = "";
  formModel.value.parentId = "";
  formModel.value.component = "";
  formModel.value.componentName = "";
  formModel.value.redirect = "";
  formModel.value.icon = "";
  formModel.value.sortNo = 0;
  formModel.value.isRoute = 0;
  formModel.value.hidden = 0;
  formModel.value.hideTab = 0;
  formModel.value.alwaysShow = 0;
  formModel.value.internalOrExternal = 0;
  formModel.value.id = "";
  formModel.value.perms = "";
  formModel.value.permsType = 1;
  formModel.value.status = "1";
};

// 添加下级打开
const addChild = (id: string) => {
  fz();
  menuList()
    .then((res) => {
      if (res.code === 200) {
        treeData.value = res.data;
      }
    })
    .finally(() => {
      option.type = 0;
      formModel.value = DefineFormModel;
      option.visible = true;
      option.title = "新增菜单";
      formModel.value.parentId = id;
      formModel.value.menuType = 1;
    });
};

defineExpose({
  show,
  edit,
  addChild,
});

const menuTreeFieldNames = {
  key: "id",
  title: "name",
  children: "children",
  icon: "icon",
};
</script>

<template>
  <a-drawer
    :width="700"
    :visible="option.visible"
    :title="option.title"
    @ok="handleOk"
    @cancel="handleCancel"
  >
    <a-form
      :model="formModel"
      ref="formRef"
      :rules="rules"
    >
      <a-form-item
        label="菜单类型"
        field="menuType"
      >
        <a-radio-group
          type="button"
          v-model="formModel.menuType"
        >
          <a-radio :value="0">目录</a-radio>
          <a-radio :value="1">菜单</a-radio>
          <a-radio :value="2">按钮</a-radio>
        </a-radio-group>
      </a-form-item>
      <!-- 按钮 -->
      <template v-if="formModel.menuType === 2">
        <a-form-item
          label="按钮名称"
          field="name"
        >
          <a-input
            v-model.trim="formModel.name"
            placeholder="请输入按钮名称"
            allow-clear
          ></a-input>
        </a-form-item>
        <a-form-item
          label="上级菜单"
          field="parentId"
        >
          <a-tree-select
            :fieldNames="menuTreeFieldNames"
            :data="treeData"
            v-model="formModel.parentId"
            placeholder="请选择上级菜单"
          ></a-tree-select>
        </a-form-item>
        <a-form-item
          label="访问路径"
          field="url"
        >
          <a-input
            v-model.trim="formModel.url"
            placeholder="请输入访问路径"
            allow-clear
          ></a-input>
        </a-form-item>
        <a-form-item
          label="按钮标识"
          field="perms"
        >
          <a-input
            v-model.trim="formModel.perms"
            allow-clear
            placeholder="请输入按钮标识"
          ></a-input>
        </a-form-item>
        <a-form-item
          label="状态"
          field="status"
        >
          <a-radio-group v-model="formModel.status">
            <!-- todo 后期设置系统字典 -->
            <a-radio value="1">有效</a-radio>
            <a-radio value="0">无效</a-radio>
          </a-radio-group>
        </a-form-item>
      </template>
      <!-- 目录 -->
      <template v-else>
        <a-form-item
          label="菜单名称"
          field="name"
        >
          <a-input
            v-model.trim="formModel.name"
            allow-clear
            placeholder="请输入菜单名称"
          ></a-input>
        </a-form-item>
        <a-form-item
          field="parentId"
          v-if="formModel.menuType === 1"
          label="上级目录"
        >
          <a-tree-select
            :fieldNames="menuTreeFieldNames"
            :data="treeData"
            v-model="formModel.parentId"
            placeholder="请选择上级目录"
          ></a-tree-select>
        </a-form-item>
        <a-form-item
          label="访问路径"
          field="url"
        >
          <a-input
            v-model.trim="formModel.url"
            allow-clear
            placeholder="请输入访问路径"
          ></a-input>
        </a-form-item>
        <a-form-item
          label="前端组件"
          field="component"
        >
          <a-input
            v-model.trim="formModel.component"
            allow-clear
            placeholder="请输入前端组件"
          ></a-input>
        </a-form-item>
        <a-form-item
          label="组件名称"
          field="componentName"
        >
          <a-input
            v-model.trim="formModel.componentName"
            allow-clear
            placeholder="请输入组件名称"
          ></a-input>
        </a-form-item>
        <a-form-item
          label="菜单图标"
          field="icon"
        >
          <menu-icon-select v-model:value="formModel.icon" />
        </a-form-item>
        <a-form-item
          label="默认跳转地址"
          field="redirect"
        >
          <a-input
            v-model.trim="formModel.redirect"
            allow-clear
            placeholder="请输入默认跳转地址"
          ></a-input>
        </a-form-item>
        <a-form-item
          label="排序"
          field="sortNo"
        >
          <a-input-number
            min="0"
            allow-clear
            v-model.trim="formModel.sortNo"
            placeholder="请输入排序"
          ></a-input-number>
        </a-form-item>
        <a-form-item
          label="聚合路由"
          field="isRoute"
        >
          <a-switch
            :checked-value="1"
            :unchecked-value="0"
            v-model="formModel.alwaysShow"
          >
            <template #checked>
              是
            </template>
            <template #unchecked>
              否
            </template>
          </a-switch>
        </a-form-item>
        <a-form-item
          label="隐藏路由"
          field="hidden"
        >
          <a-switch
            :checked-value="1"
            :unchecked-value="0"
            v-model="formModel.hidden"
          >
            <template #checked>
              是
            </template>
            <template #unchecked>
              否
            </template>
          </a-switch>
        </a-form-item>
        <a-form-item
          label="隐藏Tab"
          field="hideTab"
        >
          <a-switch
            :checked-value="1"
            :unchecked-value="0"
            v-model="formModel.hideTab"
          >
            <template #checked>
              是
            </template>
            <template #unchecked>
              否
            </template>
          </a-switch>
        </a-form-item>
        <a-form-item
          label="打开方式"
          field="internalOrExternal"
        >
          <a-switch
            :checked-value="1"
            :unchecked-value="0"
            v-model="formModel.internalOrExternal"
          >
            <template #checked>
              外部
            </template>
            <template #unchecked>
              内部
            </template>
          </a-switch>
        </a-form-item>
      </template>
    </a-form>
  </a-drawer>
</template>

<style scoped lang="scss">
</style>